package com.xy.tool.jwt;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.xy.lang.domain.Result;
import com.xy.tool.context.UserContext;

/**
 * Created by zsp on 2018/8/29.
 */
public class TokenParserImpl extends JwtBase implements TokenParser {

    private final Algorithm algorithm;
    private final String issuer;

    public TokenParserImpl(Algorithm algorithm, String issuer) {
        this.algorithm = algorithm;
        this.issuer = issuer;
    }

    @Override
    public Result<UserContext> verify(String token) {
        JWTVerifier verifier = JWT.require(algorithm)
                .withIssuer(issuer)
                .build();
        DecodedJWT decodedJWT = null;
        try {
            decodedJWT = verifier.verify(token);
        } catch (TokenExpiredException e) {
            return Result.fail(Result.UNAUTHORIZED, "token已失效");
        } catch (JWTVerificationException e) {
            return Result.fail(Result.UNAUTHORIZED, "token校验未通过");
        }

        return Result.success(getClaim(decodedJWT));
    }

    @Override
    public Result<UserContext> parse(String token) {
        DecodedJWT decodedJWT = JWT.decode(token);
        return Result.success(getClaim(decodedJWT));
    }

    protected UserContext getClaim(DecodedJWT decodedJWT) {
        UserContext userContext = new UserContext();
        userContext.setUserId(decodedJWT.getClaim(USER_ID_KEY).asLong());
        Claim claim = decodedJWT.getClaim(USER_NAME_KEY);
        if (claim != null) {
            userContext.setUserName(claim.asString());
        }
        claim = decodedJWT.getClaim(ORG_ID_KEY);
        if (claim != null) {
            userContext.setUserGroupId(claim.asLong());
        }
        claim = decodedJWT.getClaim(ORG_NAME_KEY);
        if (claim != null) {
            userContext.setUserGroupName(claim.asString());
        }
        claim = decodedJWT.getClaim(ORG_ABBR_KEY);
        if (claim != null) {
            userContext.setUserGroupAbbr(claim.asString());
        }
        claim = decodedJWT.getClaim(TENANT_ID_KEY);
        if (claim != null) {
            userContext.setTenantId(claim.asLong());
        }
        return userContext;
    }

}
